﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Linq;

namespace Tanmia.Basis
{
    public class Repository<T> : IRepository<T> where T : class
    {
        #region IRepository<T> Members

        public T Save(T entity)
        {
            T retVal = null;

            using (ISession session = SessionFactory.Session)
            using (ITransaction tx = session.BeginTransaction())
            {
                retVal = session.Save(entity) as T;
                tx.Commit();
            }

            return retVal;
        }

        public T Update(T entity)
        {
            ISession session = SessionFactory.Session;
            session.Update(entity);

            using (ITransaction tx = session.BeginTransaction())
            {
                session.Update(entity);
                tx.Commit();
            }

            return entity;
        }

        public T SaveOrUpdate(T entity)
        {
            using (ISession session = SessionFactory.Session)
            using (ITransaction tx = session.BeginTransaction())
            {
                session.SaveOrUpdate(entity);
                tx.Commit();
            }

            return entity;
        }

        public void Delete(T entity)
        {
            using (ISession session = SessionFactory.Session)
            using (ITransaction tx = session.BeginTransaction())
            {
                session.Delete(entity);
                tx.Commit();
            }
        }

        public T Get(int entityID)
        {
            ISession session = SessionFactory.Session;
            return session.Get<T>(entityID);

        }

        public IList<T> Gets()
        {
            //using (ISession session = SessionFactory.Session)
            //{
                ISession session = SessionFactory.Session;
                ICriteria criteria = session.CreateCriteria<T>();
                return criteria.List<T>();
            //}
        }

        public IList<T> Search(Dictionary<string, object> propertyValuepairs)
        {
            ISession session = SessionFactory.Session;

            ICriteria criteria = session.CreateCriteria<T>();

            foreach (string key in propertyValuepairs.Keys)
                if (propertyValuepairs[key] != null)
                    criteria.Add(Expression.Eq(key, propertyValuepairs[key]));
                else
                    criteria.Add(Expression.IsNull(key));

            return criteria.List<T>();

        }

        public IList<T> Gets(System.Linq.Expressions.Expression<Func<T, bool>> satisfy)
        {
            ISession session = SessionFactory.Session;

            return session.Query<T>().Where(satisfy).ToList();
        }

        #endregion
    }
}
